package ml.classification;

import java.util.ArrayList;
import java.util.List;

import ml.classification.filter.PostProcessingFilter;
import ml.classification.filter.PseudoGaussianVotingFilter;
import ml.classification.filter.SpeechAlways1Filter;

public class MainClassification {

	private static final boolean USE_TEST_DATA = true;
	private static final boolean USE_TRAINING_DATA = false;
	private static final boolean USE_CONTEST_DATA = false;
	private static final boolean USE_MERGED_DATA = true;
	private static final boolean USE_MERGED_DATA_NEW = false;

	private static final boolean WRITE_OUTPUT_FILES = true;

	private static final String OUTPUT_DIRECTORY = "D:/workspace/machine_learning_project/output/";
	private static final String MODEL_DIRECTORY = "D:/workspace/machine_learning_project/src/ml/models/";
	private static final String DATA_DIRECTORY = "C:/Users/Martin/Dropbox/machine_learning/data/";

	// private static final String OUTPUT_DIRECTORY =
	// "C:/users/moser/workspace/machine_learning_project/output/";
	// private static final String MODEL_DIRECTORY =
	// "C:/users/moser/workspace/machine_learning_project/src/ml/models/";
	// private static final String DATA_DIRECTORY =
	// "C:/users/moser/Dropbox/machine_learning/data/";

	public static void main(final String[] args) throws Exception {

		final String musicModelFileName = MODEL_DIRECTORY
				+ "music.SMO.Music.Model.low.FP.rate.20130605.1032.model";
		final String speechModelFileName = MODEL_DIRECTORY
				+ "speech.stacking.5pct.based.on.training_data.20130606.1622.model";

		final PostProcessingFilter musicFilter = new PseudoGaussianVotingFilter(
				25, 3, false);
		// final PostProcessingFilter speechFilter = new
		// SpecialisedSpeechFilter(
		// 5, 1, 1.00);
		final PostProcessingFilter speechFilter = new SpeechAlways1Filter();
		// final PostProcessingFilter speechFilter = new
		// PseudoGaussianVotingFilter(
		// 9, 3, true);

		final List<String> listFileNames = getFileNames();

		final List<ClassificationStatistics> listStats = new ArrayList<>();

		for (final String fileName : listFileNames) {

			final String musicTestDataFileName = buildMusicFilePath(fileName);
			final String speechTestDataFileName = buildSpeechFilePath(fileName);

			final ClassificationStatistics stats = Classification
					.classifyAndPostprocess(fileName, WRITE_OUTPUT_FILES,
							OUTPUT_DIRECTORY, USE_CONTEST_DATA,
							musicTestDataFileName, speechTestDataFileName,
							musicModelFileName, speechModelFileName,
							musicFilter, speechFilter);

			listStats.add(stats);
		}

		// calculate overall gain
		double maximumPossibleGain = 0;
		double postprocessedGainOverall = 0;
		for (final ClassificationStatistics stats : listStats) {
			maximumPossibleGain += stats.maximumGain;
			postprocessedGainOverall += stats.postprocessedGain;
		}

		System.out.println("Maximum Overall Gain: " + maximumPossibleGain);
		System.out
				.println("\nCurrent Overall Gain: "
						+ postprocessedGainOverall
						+ "    ("
						+ ((int) (postprocessedGainOverall * 100 / maximumPossibleGain))
						+ "% of maximum possible gain)\n");

		System.out.println(ClassificationStatistics.getHeader());
		for (final ClassificationStatistics stats : listStats) {

			System.out.println(stats.toString());
		}
	}

	private static String buildSpeechFilePath(final String fileName) {
		String speechTestDataFileName = DATA_DIRECTORY
				+ "test_data/speech/original/" + fileName + ".speech.arff";
		if (USE_CONTEST_DATA) {
			speechTestDataFileName = DATA_DIRECTORY
					+ "contest_data/speech/original/" + fileName
					+ "_speech.arff";
		}
		if (USE_TRAINING_DATA) {
			speechTestDataFileName = DATA_DIRECTORY
					+ "training_data/speech/original/" + fileName
					+ ".speech.arff";
		}
		return speechTestDataFileName;
	}

	private static String buildMusicFilePath(final String fileName) {
		String musicTestDataFileName = DATA_DIRECTORY
				+ "test_data/music/original/" + fileName + ".music.arff";
		if (USE_MERGED_DATA) {
			musicTestDataFileName = DATA_DIRECTORY
					+ "test_data/music/original.merged/" + fileName
					+ ".music.arff";
		}
		if (USE_MERGED_DATA_NEW) {
			musicTestDataFileName = DATA_DIRECTORY
					+ "test_data/music/original.merged.new/" + fileName
					+ ".music.arff";
		}
		if (USE_CONTEST_DATA) {
			musicTestDataFileName = DATA_DIRECTORY
					+ "contest_data/music/original/" + fileName + "_music.arff";
			if (USE_MERGED_DATA) {
				musicTestDataFileName = DATA_DIRECTORY
						+ "contest_data/music/original.merged/" + fileName
						+ "_music.arff";

			}
			if (USE_MERGED_DATA_NEW) {
				musicTestDataFileName = DATA_DIRECTORY
						+ "contest_data/music/original.merged.new/" + fileName
						+ "_music.arff";

			}
		}
		if (USE_TRAINING_DATA) {
			musicTestDataFileName = DATA_DIRECTORY
					+ "training_data/music/original/" + fileName
					+ ".music.arff";
			if (USE_MERGED_DATA) {
				musicTestDataFileName = DATA_DIRECTORY
						+ "training_data/music/original.merged/" + fileName
						+ ".music.arff";

			}
			if (USE_MERGED_DATA_NEW) {
				musicTestDataFileName = DATA_DIRECTORY
						+ "training_data/music/original.merged.new/" + fileName
						+ ".music.arff";

			}
		}
		return musicTestDataFileName;
	}

	private static List<String> getFileNames() {
		final List<String> listFileNames = new ArrayList<>();
		if (USE_CONTEST_DATA) {
			for (int i = 1; i <= 16; i++) {
				listFileNames.add(String.valueOf(i));
			}

		} else if (USE_TRAINING_DATA) {
			listFileNames.add("ARD-h4");
			listFileNames.add("ARD-h13");
			listFileNames.add("ARD-h16");
			listFileNames.add("ARD-h22");
			listFileNames.add("RTL-h11");
			listFileNames.add("RTL-h20");
			listFileNames.add("RTL-h23");
			listFileNames.add("ZDF-h2");
			listFileNames.add("ZDF-h8");
			listFileNames.add("ZDF-h20");
		} else if (USE_TEST_DATA) {
			listFileNames.add("ARD-h19");
			listFileNames.add("RTL-h5");
			listFileNames.add("RTL-h14");
			listFileNames.add("ZDF-h14");
			listFileNames.add("ZDF-h15");
		}
		return listFileNames;
	}
}
